
/* Systemprogrammierung
 * Multiplayer-Quiz
 *
 * Client
 * 
 * main.c: Hauptprogramm des Clients
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <getopt.h>
#include <stdbool.h>

#include "../common/util.h"
#include "gui/gui_interface.h"
#include "../common/rfc.h"
#include "listener.h"
#include "fragewechsel.h"

//pthread_t lthread_id;
int socketDeskriptor;  //SocketID
int clientID;


int verbindungAufbauen(int socketD_, char* port_, char* hostname_) {
	int portno;
	struct sockaddr_in serv_addr;
	struct hostent * server;
	int failure = 0;

	portno = atoi(port_);
	server = gethostbyname(hostname_);
	if (server == NULL ) {
		perror("Error, no such host");
		failure = 1;
	} else {
		bzero((char*) &serv_addr, sizeof(serv_addr));
		serv_addr.sin_family = AF_INET;

		bcopy(server->h_addr, &serv_addr.sin_addr,server->h_length);
		serv_addr.sin_port = htons(portno);

		if (connect(socketD_, (struct sockaddr*) &serv_addr, sizeof(serv_addr))
				< 0) {
			infoPrint("Error: no such host");
			failure = 1;
		}
	}
	return failure;
}

//Funktion um Login anzufordern
void loginRequest(char* name) {
	PACKET packet;
	packet.header.type = RFC_LOGINREQUEST;
	packet.header.length = htons(strlen(name));
	strncpy(packet.content.playername, name, strlen(name)); //wo ichs hol, dann wo ichs reinschreib
	packetSchreiben(packet, socketDeskriptor);
}

//Funktion um Katalog anzufordern

void catalogRequest(/*char * name*/){

	PACKET packet;
	packet.header.type = RFC_CATALOGREQUEST;
	packet.header.length = htons(0);

	//strncpy(packet.content.catalogname, name, strlen(name)); //wo ichs hol, dann wo ichs reinschreib
	packetSchreiben(packet, socketDeskriptor);
	printf("catalogRequest ausführen\n");
}




//Funktion um Fragekatalog zu auszuwählen

void preparation_onCatalogChanged(const char *newSelection){// catalogChange(const char *newSelection){
		debugPrint("Katalogauswahl: %s", newSelection);
		PACKET packet;
		packet.header.type = RFC_CATALOGCHANGE;
		packet.header.length = htons(strlen(newSelection));
	    printf("catalog changed\n");
//		send(socketDeskriptor,&head,sizeof(head),MSG_WAITALL);
//		send(socketDeskriptor,newSelection,strlen(newSelection),0);
	  //  strncpy(newSelection, packet.content.catalogname,);
	   strncpy(packet.content.catalogname, newSelection, strlen(newSelection));
	   printf("Laenge des Katalogs %i\n",strlen(newSelection));
	    packetSchreiben(packet, socketDeskriptor);
		fflush(stdout);
}





//Funktion um Spiel durch Spielleiter zu starten


void preparation_onStartClicked(const char *currentSelection){ //startGame(const char *currentSelection){

	 	debugPrint("Starte Katalog %s", currentSelection);
	 	printf("CURRENTSELECTION = %s",currentSelection);
	    printf("strlen CURRENTSELECTION = %i",strlen(currentSelection));
	    PACKET packet;
	    packet.header.type = RFC_STARTGAME;
	    packet.header.length = htons(strlen(currentSelection));
	    preparation_hideWindow();
	    printf("\nSTARTGAME.type = %i\n",packet.header.type);
	    printf("STARTGAME.length = %i\n",htons(packet.header.length));

	   // send(socketDeskriptor,&head,sizeof(head),MSG_WAITALL);
	   // send(socketDeskriptor,currentSelection,htons(packet.header.length),0);
	    strncpy(packet.content.catalogname, currentSelection, strlen(currentSelection));
	    printf("Laenge des Katalogs %i\n",strlen(currentSelection));
	    packetSchreiben(packet, socketDeskriptor);

 }
//Funktion um Frage anzufordern
void questionRequest(int socketDeskriptor){
 PACKET packet;
 packet.header.type = RFC_QUESTIONREQUEST;
 packet.header.length = 0;
 packetSchreiben(packet, socketDeskriptor);//sendet Packet
 printf("Fragenanfrage is raus!\n");




 }


void preparation_onWindowClosed(void){
    printf("Window closed\n");
    close(socketDeskriptor);
    fflush(stdout);
    exit(EXIT_SUCCESS);
}


int main(int argc, char **argv) {  //Anzahl der Variablen,Variablen

	setProgName(argv[0]);
	debugEnable();


	char *name = "unknown";
	char *server = "localhost";
	char *port = "54321";

	int ret;
	int c;
	bool usernameIsSet = false;

	//Auslesen der Übergabeparameter von "main"
	while (optind < argc) {
		int option_index = 0;

		//Definierung der möglichen Parameter
		static struct option long_options[] = { { "name", required_argument, 0,
				'n' },

		{ "server", optional_argument, 0, 's' },

		{ "port", optional_argument, 0, 'p' },

		{ "help", no_argument, 0, 'h' },

		{ 0, 0, 0, 0 } };

		//Auslesen mithilfe von getopt.h
		c = getopt_long(argc, argv, "n:s:p:h:", long_options, &option_index);

		//bei fehler --> break
		if (c == -1)
			break;

		//Unterscheidung der Argumente
		switch (c) {

		case 'n':
			//variable aus getopt.h
			name = optarg;
			usernameIsSet = true;
			break;

		case 's':
			//variable aus getopt.h
			server = optarg;
			break;

		case 'p':
			//variable aus getopt.h
			port = optarg;
			break;

		case 'h':
			//Ausgabe der Hilfe bei --h argument
			printf(
					"Simple Client\nUsage: %s -n LOGINNAME [-s HOST] [-p PORT]\n",
					argv[0]);
			break;

		default:exit(0);

			break;
		}
	}
	printf("name:%s\n", name);
	printf("server:%s\n", server);

	//Wenn der username nicht gesetzt ist, Ausgabe der Hilfe
	if (!usernameIsSet) {
		printf("Simple Client\nUsage: %s -n LOGINNAME [-s HOST] [-p PORT]\n",
				argv[0]);
		exit(0);
	}

	if (strlen(name) > 31) {
		printf("Name zu lang! Max 31 Zeichen.\n", gai_strerror(ret));
		exit(0);
	}


	//Socket anlegen
	socketDeskriptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
   int socketFragen= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	printf("Trying  ... \n");

	//Verbinden und prüfen ob Verbunden
	if (verbindungAufbauen(socketDeskriptor, port, server) == 0) {
		printf("Verbindung aufgebaut\n");
		//signal(SIGINT,cleanup_sig);//neu!!!!!!!!!!!!!!!!!
		//Initialisieren der GUI
		guiInit(&argc, &argv);
		printf("GUI init \n");

		infoPrint("Client Gruppe 1");

		//* Initialisierung: Verbindungsaufbau, Threads starten usw...

		//Erstellen des LoginRequests


	    loginRequest(name);


		printf("Login gesendet\n");

		//Auf Antwort des Servers warten und diese Überprüfen
		PACKET response = packetLesen(socketDeskriptor);

		if (response.header.type == 2) {
			printf("LoginResponse ok\n");
			clientID = response.content.clientid;

		} else if (response.header.type == 255) {
			char message[(ntohs(response.header.length))];
			strncpy(message, response.content.error.errormessage,
					ntohs(response.header.length) - 1);

			message[ntohs(response.header.length) - 1] = '\0'; // Nullterminierung

			guiShowErrorDialog(message, response.content.error.errortype);
		} else {
			guiShowErrorDialog("Verbindung zum Server verloren!",
					response.content.error.errortype);
		}


		//Listenerthread erzeugen
		pthread_t Listener_thread;
		pthread_create(&Listener_thread, NULL, (void *) &listener_main,
				&socketDeskriptor);
		//Fragewechsel-Thread erzeugen
	/*	pthread_t Fragewechsel_thread;
				pthread_create(&Fragewechsel_thread, NULL, (void *) &fragenThread,
						&socketFragen);

*/
		//An GUI mitteilen ob Spielleiter oder nicht
		if (clientID == 0)
			preparation_setMode(PREPARATION_MODE_PRIVILEGED);
		else
			preparation_setMode(PREPARATION_MODE_NORMAL);

		catalogRequest();
	//GUI Anzeigen

		preparation_showWindow();

		guiMain();

		//Resourcen freigeben usw...
		guiDestroy();
		//?
		//preparation_onWindowClosed();hier richtig?noch machen
		//?
		//break;
	}

	//Socket schließen
	close(socketDeskriptor);

	return 0;
}


/*void preparation_onCatalogChanged(const char *newSelection) {
	debugPrint("Katalogauswahl: %s", newSelection);
}

void preparation_onStartClicked(const char *currentSelection) {
	debugPrint("Starte Katalog %s", currentSelection);
}

void preparation_onWindowClosed(void) {
	debugPrint("Vorbereitungsfenster geschlossen");
	guiQuit();
}*/

void game_onAnswerClicked(int index) {
	debugPrint("Antwort %i ausgewählt", index);
}

void game_onWindowClosed(void) {
	debugPrint("Spielfenster geschlossen");
	guiQuit();
}


